package com.wps.wdztv6.service.impl;

import cn.hutool.core.util.StrUtil;
import com.mybatisflex.core.query.QueryWrapper;
import com.wps.wdztv6.common.R;
import com.wps.wdztv6.common.ResultEnum;
import com.wps.wdztv6.config.AppServersProperties;
import com.wps.wdztv6.config.WdztAppInfoConfig;
import com.wps.wdztv6.config.WdztAppinfoProperties;
import com.wps.wdztv6.entity.ThirdFile;
import com.wps.wdztv6.mapper.FileMapper;
import com.wps.wdztv6.service.FileService;
import com.wps.wdztv6.utils.DateUtil;
import com.wps.wdztv6.utils.WPS4Util;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.InputStream;
import java.nio.file.Files;
import java.util.List;

import static com.wps.wdztv6.entity.table.ThirdFileTableDef.THIRD_FILE;

@Service
@Slf4j
public class FileServiceImpl implements FileService {
    @Autowired
    private FileMapper fileMapper;

    @Autowired
    private ResourceLoader resourceLoader;
    

    @Override
    public R<ThirdFile> getFileByFileVersionId(String fileId) {
        //ThirdFile file = fileMapper.selectById(fileId);
        ThirdFile file = fileMapper.selectOneById(fileId);
        if (file == null) {
            return R.failed("文件不存在:" + fileId);
        }
        return R.success("文件查询成功", file);
    }

    @Override
    public R<ThirdFile> getLatestFileByFileId(String fileId) {
        /*LambdaQueryWrapper<ThirdFile> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ThirdFile::getGroupFileId, fileId);
        queryWrapper.orderByDesc(ThirdFile::getVersion);
        queryWrapper.last("limit 1");*/
        //ThirdFile file = fileMapper.selectOne(queryWrapper);
        QueryWrapper queryWrapper1 = QueryWrapper.create()
                .where(THIRD_FILE.GROUP_FILE_ID.eq(fileId))
                .orderBy(THIRD_FILE.VERSION.desc()).limit(1);

        ThirdFile file = fileMapper.selectOneByQuery(queryWrapper1);
        if (file == null) {
            return R.failed("文件不存在:" + fileId);
        }
        return R.success("文件查询成功", file);
    }

    @Override
    public R<ThirdFile> saveFileNewVersion(String fileId, MultipartFile file) {
        R<ThirdFile> getLast = getLatestFileByFileId(fileId);
        if (getLast.getResult() == 0) {

//            File destFile = new File(getFileSavePath(fileId,getLast.getData().getName(),getLast.getData().getVersion() + 1));
            File destFile = new File(getFileSavePath(fileId, getLast.getData().getName(), getLast.getData().getVersion() + 1));

            log.info("文件新版本，保存的目录:{}", destFile.getAbsolutePath());
            try {
                file.transferTo(destFile);
                ThirdFile newFile = ThirdFile.builder()
                        .groupFileId(fileId)
                        .id(fileId + '-' + (getLast.getData().getVersion() + 1))
                        .version(getLast.getData().getVersion() + 1)
                        .createTime(DateUtil.getCurrentSeconds())
                        .updateTime(DateUtil.getCurrentSeconds())
                        .size(destFile.length())
                        .name(getLast.getData().getName()).build();
                int result = fileMapper.insert(newFile);
                if (result > 0) {
                    return R.success("新版本保存成功", newFile);
                }
                return R.failed("新版本保存失败");
            } catch (Exception e) {
                log.error("移动文件发生错误", e);
                return R.failed("保存新版本失败，移动文件发生错误:" + fileId);
            }
        } else {
            log.error("文件不存在");
        }
        return R.failed("文件不存在");
    }

    @Override
    public R<ThirdFile> getFileByVersion(String fileId, Integer version) {
        /*LambdaQueryWrapper<ThirdFile> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ThirdFile::getGroupFileId, fileId);
        queryWrapper.eq(ThirdFile::getVersion, version);
        ThirdFile file = fileMapper.selectOne(queryWrapper);*/
        QueryWrapper queryWrapper1 = QueryWrapper.create()
                .and(THIRD_FILE.GROUP_FILE_ID.eq(fileId))
                .and(THIRD_FILE.VERSION.eq(version));
        ThirdFile file = fileMapper.selectOneByQuery(queryWrapper1);
        if (file != null) {
            return R.success("获取文件特定版本成功", file);
        } else {
            return R.failed("文件版本不存在");
        }
    }

    @Override
    public R<List<ThirdFile>> getFileHistory(String fileId) {
        /*LambdaQueryWrapper<ThirdFile> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ThirdFile::getGroupFileId, fileId);
        queryWrapper.orderByDesc(ThirdFile::getVersion);*/
        //List<ThirdFile> data = fileMapper.selectList(queryWrapper);

        QueryWrapper queryWrapper = QueryWrapper.create()
                .and(THIRD_FILE.GROUP_FILE_ID.eq(fileId))
                .orderBy(THIRD_FILE.VERSION.desc());

        List<ThirdFile> data = fileMapper.selectListByQuery(queryWrapper);
        return R.success("获取成功", data);
    }

    @Override
    public String getFileSavePath(String fileId, String filename, Integer version) {
        String ext = getFileExt(filename);
        if (version == 1) {
            return getTemplateFileSavePath(getTemplateFileTypes(filename));
        }

        return String.format("%s%s", WdztAppinfoProperties.uploadPath, fileId + version + ext);
    }

    public String getFileExt(String filename) {
        return filename.substring(filename.lastIndexOf("."));
    }

    public String getTemplateFileTypes(String filename) {
        return StrUtil.subSuf(getFileExt(filename), 1);
    }


    @Override
    public String getTemplateFileSavePath(String fileType) {

        if (StringUtils.equals(WdztAppInfoConfig.XLSX, fileType)) {
            return "classpath:templates" + File.separator + "docs" + File.separator + "template.xlsx";
        }
        if (StringUtils.equals(WdztAppInfoConfig.DOCX, fileType)) {
            return "classpath:templates" + File.separator + "docs" + File.separator + "template.docx";
        }
        if (StringUtils.equals(WdztAppInfoConfig.PDF, fileType)) {
            return "classpath:templates" + File.separator + "docs" + File.separator + "template.pdf";
        }
        if (StringUtils.equals(WdztAppInfoConfig.PPTX, fileType)) {
            return "classpath:templates" + File.separator + "docs" + File.separator + "template.pptx";
        }
        if (StringUtils.equals(WdztAppInfoConfig.PNG, fileType)) {
            return "classpath:templates" + File.separator + "docs" + File.separator + "water.png";
        }
        if (StringUtils.equals(WdztAppInfoConfig.ZIP, fileType)) {
            return "classpath:templates" + File.separator + "docs" + File.separator + "template.zip";
        }
        return null;
    }

    @Override
    public R<InputStream> getTemplateFile(String type) {
        log.info("fileType {} fileSavePath = {}", type, getTemplateFileSavePath(type));
        Resource resource = resourceLoader.getResource(getTemplateFileSavePath(type));
        try {
            return R.success("读取模版成功", resource.getInputStream());
        } catch (Exception error) {
            log.error("读取模版发生错误", error);
            return R.failed("读取模版发生错误");
        }
    }

    @Override
    public R<Long> getTemplateSize(String fileType) {
        Resource resource = resourceLoader.getResource(getTemplateFileSavePath(fileType));
        try {
            return R.success("读取模版成功", resource.contentLength());
        } catch (Exception error) {
            log.error("读取模版发生错误", error);
            return R.failed("读取模版发生错误");
        }
    }

    @Override
    public R<ThirdFile> createFileByTemplateFile(String type) {
        String name;
        String fileId;
        fileId = WPS4Util.getOrderedSequence();
        if (StringUtils.equals(type, WdztAppInfoConfig.XLSX)) {
            //fileId = WdztAppInfoConfig.templateExcelId;
            name = "新建表格文件.xlsx";
        } else if (StringUtils.equals(type, WdztAppInfoConfig.DOCX)) {
            //fileId = WdztAppInfoConfig.templateWordId;
            name = "新建文档文件.docx";
        } else if (StringUtils.equals(type, WdztAppInfoConfig.PPTX)) {
            //fileId = WdztAppInfoConfig.templatePptId;
            name = "新建演示文件.pptx";
        } else if (StringUtils.equals(type, WdztAppInfoConfig.PDF)) {
            //fileId = WdztAppInfoConfig.templatePdfId;
            name = "新建pdf文件.pdf";
        } else if (StringUtils.equals(type, WdztAppInfoConfig.PNG)) {
            //fileId = WdztAppInfoConfig.templateImgWaterId;
            name = "新建水印文件.png";
        } else if (StringUtils.equals(type, WdztAppInfoConfig.ZIP)) {
            //fileId = WdztAppInfoConfig.templateZipId;
            name = "新建压缩文件.zip";
        } else {
            return R.failed("文件类型不支持");
        }
        //ThirdFile file = fileMapper.selectById(generateVersionFileId(fileId, 1));
        ThirdFile file = fileMapper.selectOneById(generateVersionFileId(fileId, 1));
        if (file != null) {
            return R.success("文件存在，使用旧文档", file);
        }
        file = ThirdFile.builder()
                .id(generateVersionFileId(fileId, 1))
                .name(name)
                .version(1)
                .createTime(DateUtil.getCurrentSeconds())
                .updateTime(DateUtil.getCurrentSeconds())
                .size(getTemplateSize(type).getData())
                .groupFileId(fileId)
                .build();
        int insertResult = fileMapper.insert(file);
        log.info("insertResult:{}", insertResult);
        return insertResult > 0 ? R.success("创建模版文件成功", file) : R.failed("文件模版创建失败");
    }

    @Override
    public R<InputStream> downloadFile(String fileId, Integer version) {
        R<ThirdFile> dbFile = getFileByFileVersionId(generateVersionFileId(fileId, version));
        if (dbFile.getResult() != 0) {
            return R.failed(dbFile.getMessage());
        }
        ThirdFile file = dbFile.getData();
        if (version == 1) {
            return getTemplateFile(getTemplateFileTypes(file.getName()));
        }

        File fileVersion = new File(getFileSavePath(fileId, file.getName(), file.getVersion()));
        log.info("要下载的文件地址为：{}", fileVersion.getAbsolutePath());
        if (fileVersion.exists()) {
            try {
                return R.success("获取文件成功", Files.newInputStream(fileVersion.toPath()));
            } catch (Exception e) {
                return R.failed(e.getMessage());
            }
        }
        return R.failed("文件不存在");
    }

    @Override
    public String getDownloadUrl(String fileId, Integer version) {
        return String.format("%s%s?file_id=%s&version=%s", AppServersProperties.myserverUrl, "/download/file", fileId, version);
    }

    @Override
    public String generateVersionFileId(String fileId, Integer version) {
        return String.format("%s-%s", fileId, version);
    }

    @Override
    public R<String> getFileType(String filename) {
        String type = WPS4Util.getFileType(filename);
        return type != null ? R.success("获取成功", type) : R.failed("文件不支持");
    }

    @Override
    public R<ThirdFile> fileRename(String fileId, String filename) {
        R<ThirdFile> thirdFileR = getLatestFileByFileId(fileId);

        if (thirdFileR.getResult() != ResultEnum.SUCCESS.getCode()) {
            log.info("重命名时文件不存在:{}", fileId);
            //return WdztResult.failed("文件不存在存在", "请检查文件信息是否正确");
            throw new RuntimeException("重命名时文件不存在存在，请检查文件信息是否正确:" + fileId);
        }
        //ThirdFile(id=1692753245441-2, name=测试文件.docx, size=10248, version=2, createTime=1692753315, updateTime=1692753315, groupFileId=1692753245441)
        ThirdFile thirdFile = thirdFileR.getData();

        ThirdFile build = ThirdFile.builder().id(thirdFile.getId()).name(filename).build();
        //fileMapper.updateById(build);
        fileMapper.update(build);
        return R.success("文件重命名成功", build);
    }

    /**
     * 清空表数据
     */
    @Override
    public void resetFile() {
        //fileMapper.delete(null);
        fileMapper.deleteByCondition(THIRD_FILE.ID.isNotNull());

    }
}
